package org.budo.dubbo.protocol.async.config;

import java.util.HashMap;

import org.budo.dubbo.protocol.async.BudoAsyncDubboProtocol;
import org.budo.dubbo.protocol.async.repository.AsyncRepository;
import org.springframework.beans.factory.FactoryBean;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * 发消息
 * 
 * @author limin
 * 
 * @see com.alibaba.dubbo.config.spring.ReferenceBean
 */
@Slf4j
@Getter
@Setter
public class BudoAsyncReferenceBean implements FactoryBean<Object> {
    private Class<?> interfaceType;

    private String destinationName = "";

    private String asyncRepositoryBeanName;

    private String serialization = BudoAsyncDubboProtocol.DEFAULT_SERIALIZATION;

    @Override
    public Object getObject() throws Exception {
        ReferenceConfig<Object> referenceConfig = new ReferenceConfig<Object>();
        referenceConfig.setApplication(new ApplicationConfig("BudoAsyncReferenceBean"));
        referenceConfig.setInterface(interfaceType);
        referenceConfig.setUrl("budo-async://reference/" + interfaceType.getName());
        referenceConfig.setCheck(false);

        if (null == referenceConfig.getParameters()) {
            referenceConfig.setParameters(new HashMap<String, String>());
        }

        referenceConfig.getParameters().put(AsyncRepository.ASYNC_REPOSITORY_BEAN_NAME, this.getAsyncRepositoryBeanName());
        referenceConfig.getParameters().put(AsyncRepository.DESTINATION_NAME, this.destinationName());
        referenceConfig.getParameters().put(Constants.SERIALIZATION_KEY, this.getSerialization());

        Object reference = referenceConfig.get();

        log.info("#58 initReference, interfaceType=" + interfaceType + ", reference=" + reference + ", this=" + this);
        return reference;
    }

    // 指定或生成
    private String destinationName() {
        return StringUtils.isBlank(this.getDestinationName()) //
                ? "budo-async-" + this.getInterfaceType().getName() //
                : this.getDestinationName();
    }

    @Override
    public Class<?> getObjectType() {
        return this.getInterfaceType();
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}
